package com.hzzc.core.service.sdk;

import com.hzzc.BizException;
import com.hzzc.api.SSOApplicationUserAuthorityView;
import com.hzzc.api.SSOApplicationView;
import com.hzzc.api.SSOResourceView;
import com.hzzc.api.SSOUserView;
import com.hzzc.core.model.SSOApplication;
import com.hzzc.core.model.SSOResource;
import com.hzzc.core.model.SSOUser;
import com.hzzc.core.service.ApplicationService;
import com.hzzc.core.service.ResourceService;
import com.hzzc.core.service.UserResourceService;
import com.hzzc.core.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 权限服务
 * <p>
 * --内存维护用户的权限信息
 * --用户权限验证
 */
@Service
public class ApiAuthorityService {

    /**
     * 用户
     */
    @Autowired
    private UserService userService;

    @Autowired
    private ApplicationService applicationService;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private UserResourceService userResourceService;

    private static final AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * 获取用户对于单个应用的权限视图
     *
     * @param appCode
     * @param userId
     * @return
     */
    public SSOApplicationUserAuthorityView getUserApplicationUserAuthorityView(String appCode, long userId) throws BizException {
        SSOApplication ssoApplication = applicationService.selectByCode(appCode);
        if (ssoApplication == null) {
            throw new BizException(appCode + "对应的app实例不存在！");
        }
        SSOUser ssoUser = userService.selectById(userId);
        if (ssoUser == null) {
            throw new BizException(appCode + "对应的用户不存在！");
        }
        //查找用户资源列表
        List<SSOResource> ssoResources = userResourceService.getUserAllResourceInThisApp(userId, ssoApplication.getId());
        List<SSOResourceView> ssoResourceViews = ssoResources.stream().map(ss -> {
            SSOResourceView ssoResourceView = new SSOResourceView();
            BeanUtils.copyProperties(ss, ssoResourceView);
            return ssoResourceView;
        }).collect(Collectors.toList());
        SSOApplicationView ssoApplicationView = new SSOApplicationView();
        BeanUtils.copyProperties(ssoApplication, ssoApplicationView);
        SSOUserView ssoUserView = new SSOUserView();
        BeanUtils.copyProperties(ssoUser, ssoUserView);
        return new SSOApplicationUserAuthorityView(ssoApplicationView, ssoUserView, ssoResourceViews, resourceService.createResourceTreeView(ssoResources));
    }

    public boolean checkAuthority(String appCode, Long userId, String locator) {
        SSOApplication ssoApplication = applicationService.selectByCode(appCode);
        if (ssoApplication == null) {
            throw new BizException(appCode + "对应的app实例不存在！");
        }
        Set<String> locators = userResourceService.getUserAllResourceInThisApp(userId, ssoApplication.getId()).stream().map(SSOResource::getLocator).filter(l -> l != null).collect(Collectors.toSet());
        Set<String> realLocators = new HashSet<>();
        locators.forEach(l -> realLocators.addAll(Arrays.asList(StringUtils.split(l, ","))));
        Set<String> targetUrl = realLocators.stream().filter(l -> !StringUtils.isEmpty(l)).collect(Collectors.toSet());
        for (String url : targetUrl) {
            if (antPathMatcher.match(url, locator)) {
                return true;
            }
        }
        return false;
    }
}
